﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net.Sockets;
using System.Runtime.Remoting.Metadata.W3cXsd2001;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace AutoFlatnessTest.Plc
{
    public class JiEnShi
    {
        bool fresh = false;
        Socket socketji;
        bool connected = false;

        public JiEnShi(string ip, int port)
        {
            if (!connected)
            {
                socketji?.Close();
                // PLCSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                socketji = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                socketji.Connect(ip, port);
                connected = true;
            }
        }

        public void Close()
        {
            socketji?.Close();
        }

        public void Fresh()
        {
            fresh = true;
        }

        object locksend = new object();

        /// <summary>
        /// 发送信息 4秒内无响应，返回空信息
        /// </summary>
        /// <param name="mes"></param>
        /// <returns></returns>
        public string SendWait(string mes)
        {
            lock (locksend)
            {
                try
                {
                    Stopwatch tunec = new Stopwatch();
                    tunec.Restart();
                    byte[] sendmb = Encoding.Default.GetBytes(mes + "\r\n");
                    socketji?.Send(sendmb);
                    if (socketji == null)
                    {
                        return "";
                    }
                    while (socketji.Available == 0 && !fresh)
                    {
                        Thread.Sleep(100);
                        if (tunec.ElapsedMilliseconds > 4000)
                        {
                            return "";
                        }
                    }
                    if (socketji.Available == 0)
                    {
                        return "";
                    }
                    byte[] reciveby = new byte[socketji.Available];
                    Thread.Sleep(200);
                    socketji.Receive(reciveby);
                    fresh = false;
                    while (socketji.Available > 0 && !fresh)
                    {
                        byte[] recivebdy = new byte[socketji.Available];
                        socketji.Receive(recivebdy);
                    }
                    return Encoding.ASCII.GetString(reciveby);
                }
                catch (Exception)
                {
                    return "";
                    //return Encoding.Default.GetString(new byte[1]);
                }

            }
        }

        public string Send(string mes)
        {
            lock (locksend)
            {
                try
                {
                    byte[] sendmb = Encoding.Default.GetBytes(mes + "\r\n");
                    socketji?.Send(sendmb);

                    if (socketji == null)
                        return string.Empty;

                    if (socketji.Available > 0)
                    {
                        byte[] reciveby = new byte[socketji.Available];
                        socketji.Receive(reciveby);

                        return Encoding.Default.GetString(reciveby);
                    }
                    return string.Empty;
                }
                catch (Exception)
                {
                    return string.Empty;
                    //return Encoding.Default.GetString(new byte[1]);
                }
            }
        }

        /// <summary>
        /// 等待
        /// </summary>
        /// <returns></returns>
        public string Recmes()
        {
            lock (locksend)
            {
                try
                {
                    Stopwatch stopwatch = new Stopwatch();
                    stopwatch.Restart();
                    if (socketji == null)
                    {
                        return "";
                    }
                    while (socketji.Available == 0 && !fresh)
                    {
                        Thread.Sleep(100);
                        if (stopwatch.ElapsedMilliseconds > 13000)
                        {
                            return "";
                        }
                    }
                    if (socketji.Available == 0)
                    {
                        return "";
                    }
                    byte[] reciveby = new byte[socketji.Available];
                    socketji.Receive(reciveby);
                    fresh = false;
                    return Encoding.Default.GetString(reciveby);
                }
                catch (Exception)
                {
                    return "";
                    //return Encoding.Default.GetString(new byte[1]);
                }

            }
        }

        /// <summary>
        /// 等待消息 直到取消
        /// </summary>
        /// <param name="ct"></param>
        /// <returns></returns>
        public List<string> WaitInfo(CancellationToken ct)
        {
            List<string> info = new List<string>();

            while (true)
            {
                if (ct.IsCancellationRequested)
                    break;

                if (socketji.Available > 0)
                {
                    byte[] reciveby = new byte[socketji.Available];
                    socketji.Receive(reciveby);

                    info.Add(Encoding.Default.GetString(reciveby));
                }

                Thread.Sleep(100);
            }

            return info;
        }


    }
}
